package com.ktjy.util;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.util.ReflectionUtils;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * QueryUtil
 *
 * @author LILIBO
 * @since 2021-06-10
 */
public class QueryUtil {

    private static final Pattern HUMP_PATTERN = Pattern.compile("[A-Z]");
    private static final Pattern LINE_PATTERN = Pattern.compile("_(\\w)");

    /**
     * 驼峰转下划线（例如：userName -> user_name）
     *
     * @param str 驼峰命名法字符串
     * @return 下划线命名法字符串
     */
    public static String humpToLine(String str) {
        Matcher matcher = HUMP_PATTERN.matcher(str);
        StringBuilder builder = new StringBuilder();
        while (matcher.find()) {
            matcher.appendReplacement(builder, "_" + matcher.group(0).toLowerCase());
        }
        matcher.appendTail(builder);
        return builder.toString();
    }

    /**
     * 下划线转驼峰（例如：user_name -> userName）
     *
     * @param str 下划线命名法字符串
     * @return 驼峰命名法字符串
     */
    public static String lineToHump(String str) {
        str = str.toLowerCase();
        Matcher matcher = LINE_PATTERN.matcher(str);
        StringBuilder builder = new StringBuilder();
        while (matcher.find()) {
            matcher.appendReplacement(builder, matcher.group(1).toUpperCase());
        }
        matcher.appendTail(builder);
        return builder.toString();
    }

    /**
     * 实体类对应QueryWrapper
     *
     * @param <T> 实体类型
     * @param entity 实体类
     * @return 实体对应类型的QueryWrapper
     */
    public static <T> QueryWrapper<T> entityQueryWrapper(T entity) {
        Field[] fields = entity.getClass().getDeclaredFields();
        QueryWrapper<T> qw = new QueryWrapper<>();
        for (Field field : fields) {
            if (Modifier.isFinal(field.getModifiers())) {
                continue;
            }
            field.setAccessible(true);
            try {
                Object obj = field.get(entity);
                if (!ObjectUtils.isEmpty(obj)) {
                    qw.eq(QueryUtil.humpToLine(field.getName()), obj);
                }
            } catch (IllegalAccessException e) {
                return null;
            }
        }
        return qw;
    }

    /**
     * 通过反射获取对象的属性值
     *
     * @param <T> 实体类型
     * @param entity 实体类
     * @param field 字段名
     * @return 字段对应的值
     */
    public static <T> Object getValueForClass(T entity, String field) {
        PropertyDescriptor pd = null;
        try {
            Field declaredField = entity.getClass().getDeclaredField(field);
            pd = new PropertyDescriptor(declaredField.getName(), entity.getClass());
        } catch (NoSuchFieldException | IntrospectionException e) {
            e.fillInStackTrace();
        }
        Method getMethod = Objects.requireNonNull(pd).getReadMethod();
        return ReflectionUtils.invokeMethod(getMethod, entity);
    }

}
